package org.agilelang.generator.cakephp;

/*
 AgileLang - A fourth generation language(http://www.agilelang.org).

 Copyright (C) 2013 Roderick Cusirramos (roderick20@hotmail.com)

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
import java.io.File;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.agilelang.util.json.JSONException;
import org.agilelang.util.json.JSONObject;
import org.agilelang.object.attributes.MenuItem;
import org.agilelang.object.attributes.View;
import org.agilelang.object.attributes.ViewForm;
import org.agilelang.object.attributes.ViewReport;
import org.agilelang.mvc.Generator;
import org.agilelang.mvc.IController;
import org.agilelang.object.Controller;
import org.agilelang.object.Model;
import org.agilelang.object.Project;
import org.agilelang.object.attributes.Attribute;
import org.agilelang.object.attributes.Reference;

public class GControllerSimple extends Generator implements IController {

    protected Project project;
    Controller controller;
    String uses = "";

    GControllerSimple(String path_app, Project project, Controller controller) {
        this.template = "bootstrap";
        setTemplate2("cakephp");
        this.path = path_app;
        this.controllers = project.controllers;
        this.models = project.models;
        this.menus = project.menus;
        this.appName = project.application.name;
        this.controller = controller;
    }

    @Override
    public void process() {
        controller(controller);
    }

    @Override
    public void controller(Controller controller) {
        this.createDirectory(path + File.separator + "view/" + controller.name.toLowerCase());

        String views = "";
        views += view(controller.views, controller.name);
        views += viewform(controller.forms, controller.name);
        //views += viewreport(controller.reports, controller.name);
        views += viewreport_model_describe(controller.reports, controller.name);

        uses = TAB + "var $uses = array(" + uses + ");\r\n";

        String file = readStreamTpl("c_controller.php.tpl");
        file = file.replace("//nameClass//", controller.name);
        file = file.replace("//nameclass//", controller.name);
        file = file.replace("//views_str//", views);
        file = file.replace("//uses//", uses);
        createfile("controller/" + controller.name + "Controller.php", path, file);
    }

    public String search_menucakephp(String controller, String view, String caption) {
        String menu = TAB + TAB + "$this->set('menu', '');\r\n"
                + TAB + TAB + "$this->set('submenu', '');\r\n"
                + TAB + TAB + "$this->set('cakeDescription', '" + caption + "');\r\n"
                + TAB + TAB + "$this->set('title_for_layout', '" + caption + "');\r\n";
        int t = menus.size();
        for (int i = 0; i < t; i++) {
            int tt = menus.get(i).menuitems.size();
            for (int ii = 0; ii < tt; ii++) {
                MenuItem menuitem = menus.get(i).menuitems.get(ii);
                if (menuitem.controller.equals(controller) && menuitem.action.equals(view)) {
                    menu = TAB + TAB + "$this->set('menu', '" + menus.get(i).name.toLowerCase() + "');\r\n"
                            + TAB + TAB + "$this->set('submenu', '" + menuitem.name.toLowerCase() + "');\r\n"
                            + TAB + TAB + "$this->set('cakeDescription', '" + caption + "');\r\n"
                            + TAB + TAB + "$this->set('title_for_layout', '" + caption + "');\r\n";
                }
            }
        }
        return menu;
    }

    @Override
    public String view(List<View> listView, String nameController) {
        String str_views = "";
        int t = listView.size();
        for (int i = 0; i < t; i++) {
            View view = listView.get(i);
            String menu = search_menucakephp(nameController, view.name, view.caption);
            str_views += TAB
                    + "public function " + view.name.toLowerCase() + "() {\r\n"
                    + menu
                    + TAB + "}\r\n";
            String view_file =
                    TAB + "<h2><?php echo __('" + view.caption + "'); ?></h2>";
            createfile("view/" + nameController.toLowerCase() + "/" + view.name + ".ctp", path, view_file);
        }
        return str_views;
    }

    @Override
    public String viewform(List<ViewForm> viewforms, String nameController) {
        String viewforms_str = "";
        String forms_attr_str = "";
        int t = viewforms.size();
        for (int i = 0; i < t; i++) {
            ViewForm view = viewforms.get(i);
            String menu = search_menucakephp(nameController, view.name, view.caption);
            viewforms_str += TAB
                    + "public function " + view.name.toLowerCase() + "() {\r\n"
                    + menu
                    + TAB + "}\r\n";
            try {
                JSONObject j = new JSONObject(view.controls);
                Iterator it = j.keys();
                while (it.hasNext()) {
                    String label = (String) it.next();
                    JSONObject d = j.getJSONObject(label);
                    forms_attr_str +=
                            TAB + TAB + "<p>\r\n"
                            + TAB + TAB + TAB + "<label for=\"" + label + "\">" + d.get("caption").toString() + " : </label>\r\n"
                            + TAB + TAB + TAB + "<input type=\"text\" name=\"" + label + "\" id=\"" + label + "\" class=\"text ui-widget-content ui-corner-all\"/>\r\n"
                            + TAB + TAB + "</p>\r\n";
                }
            } catch (JSONException ex) {
                Logger.getLogger(GControllerSimple.class.getName()).log(Level.SEVERE, null, ex);
            }

            String view_file = TAB + "<h2><?php echo __('" + view.caption + "'); ?></h2>"
                    + TAB + "<form action=\"\" method=\"post\">\r\n"
                    + forms_attr_str
                    + TAB + TAB + "<input type=\"submit\" value=\"Submit\" class=\"ui-button ui-widget ui-state-default ui-corner-all\"/>"
                    + TAB + "</form>\r\n";


            createfile("view/" + nameController.toLowerCase() + "/" + view.name + ".ctp", path, view_file);
        }
        return viewforms_str;
    }

    @Override
    public String viewreport(List<ViewReport> viewreports, String nameController) {




        String str_views = "", pdf_view_th = "", pdf_view_td = "";
        String pdf_param = "", th_attrs = "", td_attrs = "", pdf_attrs = "", pdf_array = "", pdf_post = "", pdf_if = "", pdf_pa = "";

        int t = viewreports.size();
        for (int i = 0; i < t; i++) {
            ViewReport view = viewreports.get(i);
            uses += ",'" + view.model + "'";
            String str_forms = "", str_forms2 = "";
            String[] params = null;

            if (view.param.equals("*")) {
                params = this.getModelParams(view.model);
            } else {
                params = view.param.split(",");
            }

            /*for (int j = 0; j < params.length; j++) {
             //str_forms +=  TAB + "echo $this->Form->input('" + params[j] + "',array('fieldset'=>false,'div'=>false,'id'=>'" + params[j] + "','onchange'=>\"document.getElementById('" + params[j] + "_pdf').value = document.getElementById('" + params[j] + "').value;\" ,'class'=>'text ui-widget-content ui-corner-all'));\r\n";
             str_forms +=  TAB +"<?php echo $this->Form->input('" + params[j] + "', array('label'=>array('text'=>'" + params[j] + "','class' => 'control-label'),'id'=>'" + params[j]+"','placeholder' => '" + params[j] + "','onchange'=>\"document.getElementById('" + params[j] + "_pdf').value = document.getElementById('" + params[j] + "').value;\")); ?>\r\n";

                
                
             str_forms2 += TAB + TAB + TAB + "echo $this->Form->input('" + params[j] + "',array('type'=>'hidden','fieldset'=>false,'div'=>false,'id'=>'" + params[j] + "_pdf','class'=>'text ui-widget-content ui-corner-all'));\r\n";

             th_attrs += TAB + TAB + TAB + TAB + "<th>" + name(params[j]) + "</th>\r\n";
             td_attrs += TAB + TAB + TAB + TAB + "<td><?php echo $" + view.model.toLowerCase() + "['" + view.model + "']['" + params[j] + "']; ?></td>\r\n";
             pdf_attrs += TAB + TAB + "$" + params[j] + "=\"\";\r\n";
             pdf_array += TAB + TAB + TAB + "$" + params[j] + " = $this->data['" + nameController + "']['" + params[j] + "'];\r\n";


             pdf_if += TAB + TAB + TAB + "if(isset($this->params['named']['" + params[j] + "'])){\r\n"
             + TAB + TAB + TAB + TAB + "$" + params[j] + " = $this->params['named']['" + params[j] + "'];\r\n"
             + TAB + TAB + TAB + "}\r\n";
             pdf_pa += TAB + TAB + "$this->set('" + params[j] + "', $" + params[j] + ");\r\n";

             pdf_post += "'" + view.model + "." + params[j] + " LIKE'=> '%'.$" + params[j] + ".'%',";
             pdf_param += "'" + params[j] + "' => $" + params[j] + ",";

             pdf_view_th += "$pdf->Cell(40,7,'" + name(params[j]) + "',1,0,\"C\");\r\n";
             pdf_view_td += TAB + "$pdf->Cell(40,7,$" + view.model.toLowerCase() + "['" + view.model + "']['" + params[j] + "'],1,0,\"C\");\r\n";

             }*/
            String menu = search_menucakephp(nameController, view.name, view.caption);
            str_views += TAB
                    + "public function " + view.name.toLowerCase() + "() {\r\n"
                    + pdf_attrs
                    + TAB + TAB + "if (!empty($this->data)) {\r\n"
                    + pdf_array
                    + TAB + TAB + "}\r\n"
                    + TAB + TAB + "else{\r\n"
                    + pdf_if
                    + TAB + TAB + "}\r\n"
                    + TAB + TAB + "$this->paginate = array(\r\n"
                    + TAB + TAB + TAB + "'conditions' => array(" + pdf_post + "),\r\n"
                    + TAB + TAB + TAB + "'limit' => 10\r\n"
                    + TAB + TAB + ");\r\n"
                    + TAB + TAB + "$this->set('" + this.setPluralize(view.model).toLowerCase() + "', $this->paginate());\r\n"
                    + pdf_pa
                    + menu
                    + TAB + "}\r\n";

            String view_file = readStreamTpl("c_report.html.tpl");
            view_file = view_file.replace("//textfield_attrs//", str_forms);
            view_file = view_file.replace("//str_forms_pdf//", str_forms2);
            view_file = view_file.replace("//th_attrs//", th_attrs);
            view_file = view_file.replace("//td_attrs//", td_attrs);

            //view_file = view_file.replace("//menu_1//", menu_1);
            //view_file = view_file.replace("//menu_2//", menu_2);
            view_file = view_file.replace("//menu_3//", view.name);
            view_file = view_file.replace("//controller//", nameController);
            view_file = view_file.replace("//pdf_param//", pdf_param);
            view_file = view_file.replace("//report_name//", view.name);

            view_file = view_file.replace("//model//", view.model.toLowerCase());
            view_file = view_file.replace("//models//", this.setPluralize(view.model).toLowerCase());
            createfile("view/" + nameController.toLowerCase() + "/" + view.name + ".ctp", path, view_file);
            //-----------------------------------------------------------------

            str_views +=
                    TAB + "public function " + view.name.toLowerCase() + "pdf() {\r\n"
                    + pdf_attrs
                    + TAB + TAB + "if (!empty($this->data)) {\r\n"
                    + pdf_array
                    + TAB + TAB + "}\r\n"
                    + TAB + TAB + "else{\r\n"
                    + pdf_if
                    + TAB + TAB + "}\r\n"
                    + TAB + TAB + "$this->paginate = array(\r\n"
                    + TAB + TAB + TAB + "'conditions' => array(" + pdf_post + "),\r\n"
                    + TAB + TAB + TAB + "'limit' => 10\r\n"
                    + TAB + TAB + ");\r\n"
                    + TAB + TAB + "$this->set('" + this.setPluralize(view.model).toLowerCase() + "', $this->paginate());\r\n"
                    + TAB + TAB + "$this->layout = 'pdf';\r\n"
                    + TAB + TAB + "$this->response->type('pdf');\r\n"
                    + TAB + "}\r\n";

            view_file = "<?php\r\n"
                    + "App::import('Vendor','PDF');\r\n"
                    + "$pdf = new PDF();\r\n"
                    + "$pdf->title = '" + view.name + "';\r\n"
                    + "$pdf->AddPage();\r\n"
                    + "$pdf->SetFont('Arial','B',10);\r\n"
                    + pdf_view_th
                    + "$pdf->Ln();\r\n"
                    + "$pdf->SetFont('Arial','',10);\r\n"
                    + "foreach( $" + this.setPluralize(view.model).toLowerCase() + " as $" + view.model.toLowerCase() + " ){\r\n"
                    + pdf_view_td
                    + TAB + "$pdf->Ln();"
                    + "}"
                    + "$pdf->Output();\r\n"
                    + "?>";
            createfile("view/" + nameController.toLowerCase() + "/" + view.name + "pdf.ctp", path, view_file);
        }
        return str_views;
    }

    public String viewreport_model_describe(List<ViewReport> viewreports, String nameController) {

        int t = viewreports.size();
        String view_file = "";

        for (int i = 0; i < t; i++) {
            ViewReport view = viewreports.get(i);
            if (view.type.equals("model_describe")) {
                Model model = this.getModelByName(view.model);
                List<Attribute> attrs = model.attributes;
                List<Reference> references = model.references;
                Collections.sort(attrs, new CustomComparator2());
                String attrs_r = "";
                int tt = attrs.size();
                for (int j = 0; j < tt; j++) {
                    Attribute attr = attrs.get(j);
                    if (attr.name.endsWith("_id")) {
                        int tr = references.size();
                        for (int jj = 0; jj < tr; jj++) {
                            Reference reference = references.get(jj);
                            if (attr.name.equals(reference.foreign_key)) {
                                attrs_r += "$pdf->Cell(40,10,utf8_decode('" + attr.caption + "'),1);\n";//$article['Article']['code']
                                attrs_r += "$pdf->Cell(40,10,utf8_decode($"+model.name.toLowerCase()+"['"+reference.model_reference+"']['" + reference.field_reference + "']),1);\n$pdf->Ln();\n";
                                
                                break;
                            }
                        }
                    } else {
                        if (attr.type.equals("boolean")) {
                            
                            attrs_r += "$pdf->Cell(40,10,utf8_decode('" + attr.caption + "'),1);\n";
                            attrs_r += "$pdf->Cell(40,10,$"+model.name.toLowerCase()+"['"+model.name+"']['" + attr.name + "']== '1' ? 'Si' :'No',1);\n$pdf->Ln();\n";
                                
                        } else {

                            attrs_r += "$pdf->Cell(40,10,utf8_decode('" + attr.caption + "'),1);\n";
                            attrs_r += "$pdf->Cell(40,10,utf8_decode($"+model.name.toLowerCase()+"['"+model.name+"']['" + attr.name + "']),1);\n$pdf->Ln();\n";
                                
                        }
                    }




                }


                view_file += TAB + "public function " + view.name.toLowerCase() + "($id = null) {\r\n"
                        + "$this->"+model.name+"->id = $id;\r\n"
                        + "if (!$this->"+model.name+"->exists()) {\r\n"
                        + "throw new NotFoundException(__('Invalid "+model.name+"'));\r\n"
                        + "}\r\n"
                        + "$"+model.name.toLowerCase()+" = $this->"+model.name+"->read(null, $id);  \r\n"
                        + "App::import('Vendor','PDF');\r\n"
                        + "$pdf = new PDF();\r\n"
                        + "$pdf->title = '" + view.caption + "';\r\n"
                        + "$pdf->AddPage();\r\n"
                        + "$pdf->SetFont('Arial','B',10);\r\n"
                        + "$pdf->Ln();\r\n"
                        + "$pdf->SetFont('Arial','',10);\r\n"
                        + attrs_r
                        + "$pdf->Output();\r\n"
                        + TAB + TAB + "$this->layout = 'pdf';\r\n"
                        + TAB + TAB + "$this->response->type('pdf');\r\n"
                        + "}\n";
            }
        }
        return view_file;
    }

    public class CustomComparator2 implements Comparator<Attribute> {

        @Override
        public int compare(Attribute o1, Attribute o2) {
            return o1.item.compareTo(o2.item);
        }
    }
}
